﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BitPortal.Models;
using System.Linq.Expressions;
using BitPortal.Utils;

namespace BitPortal.Business
{
    public static partial class DiscussionBLL
    {
        public static int Insert(this Discussion discussion)
        {
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            bitEnt.Discussions.AddObject(discussion);
            return bitEnt.SaveChanges();
        }

        /// <summary>
        /// Xoa truc tiep
        /// </summary>
        /// <param name="DiscussionID"></param>
        /// <returns></returns>
        public static void DeletePermanently(Discussion d, ExtendedBitPortalEntities bitEnt)
        {
            //xoa tat ca nhung comment con
            foreach (Discussion child in bitEnt.Discussions.Where(ent => ent.IsReplyOf == d.DiscussionID))
            {
                DeletePermanently(child,bitEnt);
            }
            bitEnt.Discussions.DeleteObject(d);
        }
        public static void DeletePermanently(long discussionId, bool deleteAllChild = false)
        {
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            Discussion d = bitEnt.Discussions.SingleOrDefault(ac => ac.DiscussionID == discussionId);
            if (d != null)
            {
                if (deleteAllChild)
                {
                    DeletePermanently(d, bitEnt);
                }
                else
                {
                    //comment con
                    foreach (Discussion child in bitEnt.Discussions.Where(ent => ent.IsReplyOf == d.DiscussionID))
                    {
                        child.IsReplyOf = d.IsReplyOf;
                    }
                    bitEnt.Discussions.DeleteObject(d);
                }
            }
            bitEnt.SaveChanges();
        }

        /// <summary>
        /// Xoa tam thoi(dat IsDeleted = true)
        /// </summary>
        /// <param name="DiscussionID"></param>
        /// <returns></returns>
        public static void Delete(Discussion d, ExtendedBitPortalEntities bitEnt)
        {
            //xoa tat ca nhung comment con
            foreach (Discussion child in bitEnt.Discussions.Where(ent => ent.IsReplyOf == d.DiscussionID))
            {
                Delete(child, bitEnt);
            }
            d.IsDeleted = true;
        }
        public static void Delete(long discussionId)
        {
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            Discussion d = bitEnt.Discussions.SingleOrDefault(ac => ac.DiscussionID == discussionId);
            if (d != null)
            {
                Delete(d, bitEnt);
            }
            bitEnt.SaveChanges();
        }

        /// <summary>
        /// Lay ra danh sach tat ca comment con chau cua comment hien tai.
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="childs"></param>
        public static void GetAllChilds(this Discussion parent, List<Discussion> childs)
        {
            if (parent == null)
            {
                foreach (Discussion ac in GetAll().Where(ent => ent.IsReplyOf == null).ToList())
                {
                    childs.Add(ac);
                    GetAllChilds(ac, childs);
                }
            }
            else
            {
                foreach (Discussion ac in GetAll().Where(ent => ent.IsReplyOf == parent.DiscussionID).ToList())
                {
                    childs.Add(ac);
                    GetAllChilds(ac, childs);
                }
            }

        }

        /// <summary>
        /// Lay danh sach nhung comment cha cua comment hien tai.
        /// </summary>
        /// <param name="childArtCate"></param>
        /// <returns></returns>
        public static List<Discussion> GetParents(this Discussion childArtCate)
        {
            List<Discussion> listParents = new List<Discussion>();

            while (childArtCate.IsReplyOf != null)
            {
                childArtCate = GetAll().SingleOrDefault(ent => ent.DiscussionID == childArtCate.IsReplyOf);
                if (childArtCate == null)
                {
                    break;
                }
                listParents.Add(childArtCate);
            }

            return listParents;
        }

        /// <summary>
        /// Lay ra danh sach comment tra loi commnet hien tai.
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        public static List<Discussion> GetChilds(this Discussion parent)
        {
            if (parent == null)
            {
                return GetAll().Where(ac => ac.IsReplyOf == null).ToList();
            }
            return GetAll().Where(ac => ac.IsReplyOf == parent.DiscussionID).ToList();
        }

        /// <summary>
        /// Lay ra danh sach tat ca du lieu
        /// </summary>
        /// <returns></returns>
        public static IQueryable<Discussion> GetAll()
        {
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            var list = from ac in bitEnt.Discussions
                       where ac.IsDeleted == false
                       orderby ac.DiscussionID descending
                       select ac;
            return list;
        }

        /// <summary>
        /// Lay ra doi tuong theo ID
        /// </summary>
        /// <param name="DiscussionID"></param>
        /// <returns></returns>
        public static Discussion GetByID(int DiscussionID)
        {
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            return bitEnt.Discussions.SingleOrDefault(ac => ac.DiscussionID == DiscussionID);
        }

        public static IQueryable<Discussion> GetByCondition(string languageCode = null, long? groupId = -1, long? isReplyOf = -1, bool? isEnabled = null, bool? isDeleted = false)
        {
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            return bitEnt.Discussions.Where(ent =>
                (languageCode == null || ent.LanguageCode == languageCode) &&
                (groupId == -1 || ent.DiscussionGroupID == groupId) &&
                (isReplyOf == -1 || (ent.IsReplyOf == null && isReplyOf == null) || (ent.IsReplyOf == isReplyOf)) &&
                (isEnabled == null || ent.IsEnabled == isEnabled) &&
                (isDeleted == null || ent.IsDeleted == isDeleted)
                ).OrderByDescending(ent => ent.DiscussionID);
        }
        /// <summary>
        /// Lay du lieu theo dieu kien truyen vao
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="languageCode"></param>
        /// <param name="isReplyOf"></param>
        /// <param name="isEnabled"></param>
        /// <param name="start"></param>
        /// <param name="limit"></param>
        /// <param name="sort"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        public static IQueryable<Discussion> GetByCondition<T>(string languageCode = null, long? groupId = -1, long? isReplyOf = -1, bool? isEnabled = null, bool? isDeleted = false, int start = -1, int limit = -1, string sort = "DiscussionID", string dir = "DESC")
        {
            var list = GetAll().Where(ent =>
                (languageCode == null || ent.LanguageCode == languageCode) &&
                (groupId == -1 || ent.DiscussionGroupID == groupId) &&
                (isReplyOf == -1 || (ent.IsReplyOf == null && isReplyOf == null) || (ent.IsReplyOf == isReplyOf)) &&
                (isEnabled == null || ent.IsEnabled == isEnabled) &&
                (isDeleted == null || ent.IsDeleted == isDeleted)
                );
            //Start Sorting
            if (sort != null)
            {
                if (sort != "DiscussionID")
                {
                    var param = Expression.Parameter(typeof(Discussion), "ent");
                    var sortExpression = Expression.Lambda<Func<Discussion, T>>(Expression.Property(param, sort), param);
                    if (dir == "DESC")
                    {
                        list = list.OrderByDescending(sortExpression).ThenByDescending(ent => ent.DiscussionID);
                    }
                    else
                    {
                        list = list.OrderBy(sortExpression).ThenByDescending(ent => ent.DiscussionID);
                    }
                }
                else
                {
                    if (dir == "DESC")
                    {
                        list = list.OrderByDescending(ent => ent.DiscussionID);
                    }
                    else
                    {
                        list = list.OrderBy(ent => ent.DiscussionID);
                    }
                }
            }
            //Start Paging
            if (start >= 0 && limit > 0)
            {
                list = list.Skip(start).Take(limit);
            }
            return list;
        }
    }
}